package com.kx.talk.controller;

import com.alibaba.fastjson.JSONObject;
import com.kx.base.controller.BaseController;
import com.kx.base.dto.push.MessageDTO;
import com.kx.base.result.R;
import com.kx.base.util.SnowFlakeUtil;
import com.kx.base.vo.UserVO;
import com.kx.talk.cache.UserCache;
import com.kx.talk.client.PushClient;
import com.kx.talk.dto.MessageRecordDTO;
import com.kx.talk.dto.ReadStateDTO;
import com.kx.talk.dto.TalkMessageDTO;
import com.kx.talk.pojo.Message;
import com.kx.talk.service.TalkService;
import com.kx.talk.vo.UnReadCountVO;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 聊天的Controller
 *
 * @author Sun
 * @date 2021/8/2 21:44
 */
@RestController
@RequestMapping("kx/talk")
public class TalkController extends BaseController {
    @Resource
    private SnowFlakeUtil snowFlakeUtil;

    @Resource
    private TalkService talkService;

    @Resource
    private PushClient pushClient;

    @Resource
    private UserCache userCache;

    /**
     * 单人聊天的接口
     */
    @PostMapping("sendmessage")
    public R sendMessage(@RequestBody TalkMessageDTO talkMessageDTO) {
        //发送人，也就是当前登录用户
        Long userId = userId();
        //接收人id
        Long receiveUserId = talkMessageDTO.getToUserId();
        //发送的信息
        String message = talkMessageDTO.getMessage();
        //消息的类型
        Long messageTypeId = talkMessageDTO.getMessageType();
        int result = talkService.sendMessage(userId, receiveUserId, message, messageTypeId);
        if (result == -1) {
            //对方已经删除了自己
            return R.error(501, "您与对方不是朋友关系");
        } else if (result == 0) {
            //消息发送失败
            return R.error(502, "消息发送失败");
        } else if (result == 1) {
            //消息发送成功
            //推送消息
            //给接收人推送消息
            MessageDTO msgDTO = new MessageDTO();
            msgDTO.setRequestId(snowFlakeUtil.nextId());
            msgDTO.setUid(receiveUserId);
            msgDTO.setServiceId(1);
            JSONObject talkMsg = new JSONObject();
            talkMsg.put("message", message);
            talkMsg.put("messageType", messageTypeId);
            talkMsg.put("user", user());
            talkMsg.put("description", "单人聊天");
            msgDTO.setMessage(JSONObject.toJSONString(talkMsg));
            pushClient.pushWeb(msgDTO);
            return R.ok("发送成功");
        } else {
            return R.error(500, "未知异常");
        }
    }


    /**
     * 设置一个消息的已读与未读状态
     * 需要接收什么参数才能唯一确定一个消息？
     * 之前使用的是id，现在id之所以不好用了，是因为我们不确定是哪张表。
     * 水平拆分完表之后，表的数据满不满足第二范式？
     * 如果前端能给我确定表的关键信息，其实id就又可用了。.
     * 什么能确定表？发送人id与接收人id
     */
    @PutMapping("messagestate")
    public R readMessage(@RequestBody ReadStateDTO readStateDTO) {
        Long sendUserId = readStateDTO.getSendUserId();
        Long userId = userId();
        Long receiveUserId = readStateDTO.getReceiveUserId();
        Long messageId = readStateDTO.getMessageId();
        Integer readState = readStateDTO.getReadState();
        if (!userId.equals(sendUserId)) {
            return R.error(501, "您无法设置此消息");
        }
        Integer result = talkService.modifyMessageReadState(sendUserId, receiveUserId, messageId, readState);
        if (result == 0) {
            return R.error(502, "消息状态设置失败");
        } else if (result == 1) {
            return R.ok(200, "消息状态设置成功");
        } else {
            return R.error(502, "未知错误");
        }
    }

    /**
     * 查询两个人的聊天记录
     * 1、在表已经横向拆分之时，对数据库的表进行分页查询？
     * 张三给李四发送的消息，因为一定在某一张表里
     * 李四给张三发送的消息，也一定在某一张表里
     * 综上：其实就是两张表的合并分页查询问题。
     * 2、对于已经横向拆分的表，如何认定主键？ 已解决。
     * 3、两个表混在一起查，如何排序？
     * 注意：千万不能用id排序
     * 应该用create_time之类的时间来排序
     */
    @PostMapping("chatrecord")
    public R chatRecord(@RequestBody MessageRecordDTO messageRecordDTO) {
        Long selfId = messageRecordDTO.getSelfId();
        Long otherId = messageRecordDTO.getOtherId();
        Long selfLastItemId = messageRecordDTO.getSelfLastItemId();
        Long otherLastItemId = messageRecordDTO.getOtherLastItemId();
        Integer pageSize = messageRecordDTO.getPageSize();
        List<Message> messages = talkService.selectPageChartRecord(selfId, otherId, selfLastItemId, otherLastItemId,pageSize);
        UserVO self = user();
        UserVO other = userCache.getUser(otherId);

        return R.ok(200, "查询成功")
                .setResult("message", messages)
                .setResult("self", self)
                .setResult("other", other);
    }

    /**
     * 查询单个用户的未读消息的总数
     */
    @GetMapping("unread")
    public R selectUnReadCount(){
        Long userId=userId();
        long count = talkService.selectUnreadCountByUserId(userId);
        return R.ok(200,"查询成功").setResult("count",count);
    }

    /**
     * 根据好友id分组求未读消息总数
     */
    @GetMapping("unreadGroupBy")
    public R selectUnReadGroupByCount(){
        Long userId=userId();
        List<UnReadCountVO> unReadCountVOS = talkService.selectUnReadCountGroupBy(userId);
        return R.ok(200,"查询成功").setResult("friendCounts",unReadCountVOS);
    }
}
